package cn.niceff.middleware.dynamic.thread.pool.sdk.domain;

import cn.niceff.middleware.dynamic.thread.pool.sdk.domain.model.entity.ThreadPoolConfigEntity;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author niceff.cn
 * @apiNote 线程池服务, 使用内存来存储线程池对象, 利用map的数据结构来存储.
 */
public class PoolServiceImpl implements IPoolService {
    private static final Logger logger = org.slf4j.LoggerFactory.getLogger(PoolServiceImpl.class);

    /**
     * 应用名称
     */
    private final String applicationName;

    /**
     * 线程池map
     * key: 线程池名称
     * value: 线程池对象
     */
    private final Map<String, ThreadPoolExecutor> threadPoolMap;

    public PoolServiceImpl(String applicationName, Map<String, ThreadPoolExecutor> threadPoolMap) {
        this.applicationName = applicationName;
        this.threadPoolMap = threadPoolMap;
        logger.info("PoolServiceImpl initialized with applicationName: {}, threadPoolMap size: {}", applicationName, threadPoolMap.size());
    }

    /**
     * 查询线程池配置信息列表
     *
     * @return 返回包含所有线程池配置信息的列表，每个配置信息包括线程池的名称、核心线程数、活跃线程数、当前线程池中的线程数、最大线程池线程数、
     * 当前队列的任务数、队列类型、以及队列中还可以容纳的任务数量
     */
    @Override
    public List<ThreadPoolConfigEntity> queryThreadPoolList() {
        logger.info("获取线程池的线程信息列表: {},  \n >>>>>>>>>>>>", JSON.toJSONString(threadPoolMap));
        List<ThreadPoolConfigEntity> resList = new ArrayList<>();
        threadPoolMap.forEach((k, v) -> resList.add(fillThreadPoolConfigEntity(k, v)));
        return resList;
    }

    /**
     * 根据线程池名称查询线程池配置信息
     *
     * @param threadPoolName 线程池名称
     * @return 返回对应的线程池配置实体，如果不存在则返回null
     */
    @Override
    public ThreadPoolConfigEntity queryThreadPoolConfigByName(String threadPoolName) {
        ThreadPoolExecutor threadPoolExecutor = threadPoolMap.get(threadPoolName);
        // 填充数据
        return fillThreadPoolConfigEntity(threadPoolName, threadPoolExecutor);
    }

    /**
     * 根据threadPoolName来更新线程池配置信息
     *
     * @param threadPoolConfigEntity 线程池配置实体，包含需要更新的线程池配置信息
     * @throws NullPointerException 如果传入的threadPoolConfigEntity为null，则抛出此异常
     * @apiNote 此方法仅仅只是更新 最大核心数和 最大线程数.
     */
    @Override
    public void updateThreadPoolConfig(ThreadPoolConfigEntity threadPoolConfigEntity) {
        if (null == threadPoolConfigEntity || !applicationName.equals(threadPoolConfigEntity.getAppName())) {
            throw new NullPointerException("线程池配置信息为空或者应用名称不匹配");
        }
        if (!StringUtils.hasText(threadPoolConfigEntity.getThreadPoolName())) {
            throw new NullPointerException("线程池名称为空");
        }
        ThreadPoolExecutor threadPoolExecutor = threadPoolMap.get(threadPoolConfigEntity.getThreadPoolName());
        if (null == threadPoolExecutor) {
            return;
        }
        // 核心线程数
        threadPoolExecutor.setCorePoolSize(threadPoolConfigEntity.getCorePoolSize());
        // 最大线程数
        threadPoolExecutor.setMaximumPoolSize(threadPoolConfigEntity.getMaximumPoolSize());
    }

    /**
     * 将线程池对象实体, 转化为配置信息的实体类
     *
     * @param threadPoolExecutor 线程池对象
     * @return 线程池配置信息实体类
     */
    private ThreadPoolConfigEntity fillThreadPoolConfigEntity(String threadPoolName, ThreadPoolExecutor threadPoolExecutor) {
        if (threadPoolExecutor == null) {
            return null;
        }
        if (!StringUtils.hasText(threadPoolName)) {
            return null;
        }
        ThreadPoolConfigEntity info = new ThreadPoolConfigEntity(applicationName, threadPoolName);
        // 核心线程数
        info.setCorePoolSize(threadPoolExecutor.getCorePoolSize());
        // 活跃线程数(正在执行任务的)
        info.setActiveCount(threadPoolExecutor.getActiveCount());
        // 当前线程池中的线程数
        info.setPoolSize(threadPoolExecutor.getPoolSize());
        // 最大线程池线程数
        info.setMaximumPoolSize(threadPoolExecutor.getMaximumPoolSize());
        // 当前队列的任务数
        info.setQueueSize(threadPoolExecutor.getQueue().size());
        // 基于阻塞队列实现
        info.setQueueType(threadPoolExecutor.getQueue().getClass().getTypeName());
        // 队列中还可以容纳的元素(任务)数量
        info.setRemainingCapacity(threadPoolExecutor.getQueue().remainingCapacity());
        return info;
    }
}
